package com.project.common.exception;

import com.framework.core.result.APIObjResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
* @Description:   系统异常统一拦截
* @Author:         wangzhiqiang
* @CreateDate:     2019-02-22 18:03
* @Version:        1.0
*/
@ControllerAdvice
@ResponseBody
@Slf4j
public class ExceptionHandle {

    /**
     * 登录异常拦截
     * @param e
     * @return
     */
    @ExceptionHandler(value = LoginException.class)
    public APIObjResponse loginException(LoginException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getCode(), e.getMessage());
    }

    /**
     * 微信根据临时凭证CODE获取openid异常拦截
     * @param e
     * @return
     */
    @ExceptionHandler(value = Jscode2sessionException.class)
    public APIObjResponse jscode2sessionException(Jscode2sessionException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getCode(), e.getMessage());
    }

    /**
     * 参数异常拦截
     * @param e
     * @return
     */
    @ExceptionHandler(value = ArgsException.class)
    public APIObjResponse argsException(ArgsException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 比较异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = ComparatorException.class)
    public APIObjResponse comparatorException(ComparatorException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * HTTP异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpException.class)
    public APIObjResponse httpException(HttpException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * IO异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = IORuntimeException.class)
    public APIObjResponse iORuntimeException(IORuntimeException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 注册异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = RegisterException.class)
    public APIObjResponse registerException(RegisterException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getCode(), e.getMessage());
    }

    /**
     * 服务异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = ServiceException.class)
    public APIObjResponse serviceException(ServiceException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 带有状态码的异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = StatefulException.class)
    public APIObjResponse statefulException(StatefulException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 工具类异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = UtilException.class)
    public APIObjResponse utilException(UtilException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 验证异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = ValidateException.class)
    public APIObjResponse validateException(ValidateException e){
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 所有异常拦截
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public APIObjResponse exceptionHandle(Exception e){
        log.error(e.getMessage(),e);
        printExceptionMessage(e);
        return APIObjResponse.error(e.getMessage());
    }

    /**
     * 参数验证异常
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public APIObjResponse validationError(MethodArgumentNotValidException ex) {
        log.error("raised MethodArgumentNotValidException : " + ex);
        List<FieldError> fieldErrorList = ex.getBindingResult().getFieldErrors();
        if(fieldErrorList.size()>0){
            FieldError error = fieldErrorList.get(0);
            return APIObjResponse.error(error.getDefaultMessage());
        }
        return APIObjResponse.error("MethodArgumentNotValidException");
    }

    /**
     * 服务器返回找不到客户端异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = ClientAbortException.class)
    public APIObjResponse clientAbortException(ClientAbortException e){
        return APIObjResponse.error("服务器返回找不到客户端异常");
    }

    /**
     * 打印异常信息
     * @param e
     */
    private void printExceptionMessage(Exception e){
        StackTraceElement stElement = e.getStackTrace()[0];
        String exClass = stElement.getClassName();
        String method = stElement.getMethodName();
        String message = "[类:" + exClass + "]调用" + method + "时在第" + stElement.getLineNumber() + "行代码处发生异常!异常类型:" + e.getClass().getName();
        log.error(message);
    }

}
